package gameobjects;

import gamecontrol.CurrentBoard;

public class Hero extends Element {
 
	public final static int up = 1;
	 
	public final static int down = 2;
	 
	public final static int left = 3;
	 
	public final static int right = 4;
	 
	private CurrentBoard currentBoard;
	
        /**
         * 
         * @param movement
         * @return true if the hero has moved, false if not.
         */
	public boolean move(int movement) {
            //if is possible to move change the elements
            int heroPositionX = this.getBox().getPositionX();
            int heroPositionY = this.getBox().getPositionY();
            int targetPositionX = heroPositionX;
            int targetPositionY = heroPositionY;
            boolean movePossible = false;
            
            switch(movement){
                case(Hero.up):
                    targetPositionY = targetPositionY +1;
                    break;
                case(Hero.down):
                    targetPositionY = targetPositionY -1;
                    break;
                case(Hero.left):
                    targetPositionX = targetPositionX -1;
                    break;
                case(Hero.right):
                    targetPositionX = targetPositionX +1;
                    break;    
            }
            
            /* the hero possibilities to move:
             * 1) Towards to a beer, the hero take this, add points and update de board
             * 2) Towards to a weight, the hero can move this if it has clean terrein
             *      in this direction of the movement if it is left or right
             * 3) Towards to a terrein
             * 4) Towards to a exit, the user pass to the next level
             * 5) Towards to a wall, the user cannot move, nothing happens
             * 6) Towards to a magic wall, the user cannot move, nothing happens
             * 7) Towards to a expanding wall, the user cannot move, nothing happens
             * 8) Towards to a firefly, the user lost a life
             * 9) Towards to a butterfly, the user lost a life
             * 10) Towards to a amoeba, the user cannot move, nothing happens
            */
            char targetId = this.getCurrentBoard().getBoxes().getBox(targetPositionX, targetPositionY).getElement().getId();
            
            switch(targetId){
                ////////////////////////////////////////////////////////////////
                case(Element.BeerId):
                    this.currentBoard.getBoxes().swapBoxes(heroPositionX, heroPositionY, targetPositionX, targetPositionY);
                    //convert the beer into clean terrain
                    Element e = new Terrain();
                    ((Terrain)e).setAsCleanTerrain();
                    e.setId(Element.CleanTerrainId);
                    e.setPriority(Element.CleanTerrainPriority);
                    e.setBox(this.currentBoard.getBoxes().getBox(heroPositionX,heroPositionY));
                    e.getBox().setElement(e);
                    //add the puntuation to the user
                    this.currentBoard.getGame().increaseCurrentScore(200);
                    //remove a beer from the existing
                    this.currentBoard.removeABeer();
                    //check if was the last beer and open the exit if was necessary
                    if(this.currentBoard.getRemaningBeers()==0){
                        this.currentBoard.openExitDoor();
                    }
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.WeightId):
                    //check if the weight must be moved
                    int targetPosition2X = 0;
                    switch(movement){
                        case(Hero.up):
                            movePossible = false;
                            break;
                        case(Hero.down):
                            movePossible = false;
                            break;
                        case(Hero.left):
                            targetPosition2X = targetPositionX-1;
                            movePossible = true;
                            break;
                        case(Hero.right):
                            targetPosition2X = targetPositionX+1;
                            movePossible = true;
                            break;
                    }
                    //if has possibility that the neighbour is clean terrain
                    if(movePossible){
                        //if the neighbour is clean terrain, move the weight
                        if(this.currentBoard.getBoxes().getBox(targetPosition2X, heroPositionY).getElement().getId()==Element.CleanTerrainId){
                            //It is necessary two movements:
                            //first swap clean terrain with weight
                            this.currentBoard.getBoxes().swapBoxes(targetPositionX, targetPositionY, targetPosition2X, targetPositionY);
                            //second swap the new clean terrain with hero
                            this.currentBoard.getBoxes().swapBoxes(heroPositionX, heroPositionY, targetPositionX, targetPositionY);
                            movePossible = true;
                        }
                        else{
                            movePossible = false;
                        }
                    }
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.DirtyTerrainId):
                    this.currentBoard.getBoxes().swapBoxes(heroPositionX, heroPositionY, targetPositionX, targetPositionY);
                    //put the dirty terrein as clean
                    ((Terrain)this.currentBoard.getBoxes().getBox(heroPositionX, heroPositionY).getElement()).setAsCleanTerrain();
                    //modificates the id to clean
                    ((Terrain)this.currentBoard.getBoxes().getBox(heroPositionX, heroPositionY).getElement()).setId(Element.CleanTerrainId);
                    movePossible = true;
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.CleanTerrainId):
                    this.currentBoard.getBoxes().swapBoxes(heroPositionX, heroPositionY, targetPositionX, targetPositionY);
                    movePossible = true;
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.ExitId):
                    if(this.goIntoExit(targetPositionX, targetPositionY)){
                        this.currentBoard.getGame().increaseCurrentScore(200);
                        this.currentBoard.getGame().advanceToNextLevel();
                        movePossible = true;
                    }
                    else{
                    }
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.WallId):
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.MagicWallId):
                    movePossible = false;
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.ExpandingWallId):
                    movePossible = false;
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.FireFlyId):
                    this.currentBoard.getGame().subtractALife();
                    movePossible = true;
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.ButterFlyId):
                    this.currentBoard.getGame().subtractALife();
                    movePossible = true;
                    break;
                ////////////////////////////////////////////////////////////////
                case(Element.AmoebaId):
                    movePossible = false;
                    break;    
            }
            
            return movePossible;
	}
	
        /**
         * Try to catch an element of the board.
         * @return true if the element is catched, false if not.
         */
	public boolean catchElement() {
		return false;
	}
        
        /**
         * 
         * @return true if the hero go into the exit and this is visible, false if not
         */
        public boolean goIntoExit(int positionX, int positionY) {
            if(((Exit)this.currentBoard.getBoxes().getBox(positionX, positionY).getElement()).getVisible())
                return true;
            else
                return false;
        }
        
        /**
         * 
         * @return
         */
        public CurrentBoard getCurrentBoard(){
            return currentBoard;
        }
        
        /**
         * 
         * @param currentBoard
         */
        public void setCurrentBoard(CurrentBoard currentBoard){
            this.currentBoard = currentBoard;
        }
	 
}
 
